import numpy as np
from scipy import stats

def find_min_n_for_p(p0=0.1, alpha=0.05, delta_start=0.001, delta_end=0.05, delta_step=0.001, max_n=10000):
    z_alpha_2 = stats.norm.ppf(1 - alpha/2)
    print(f"z_(α/2) = {z_alpha_2:.4f}")
    print(f"检验条件: |z| > {z_alpha_2:.4f}")
    print(f"{'p':>8} {'min_n':>8} {'示例k':>8} {'p̂':>8} {'SE':>10} {'z':>8} {'|z|':>8} {'满足条件':>8}")

    delta = delta_start
    while delta <= delta_end:
        p = p0 + delta
        n = 10
        found = False
        while n <= max_n:
            # k ~ B(n, p)
            k = np.random.binomial(n, p)
            # 样本次品率
            p_hat = k / n
            # 标准误差
            SE = np.sqrt(p_hat * (1 - p_hat) / n) if n > 0 else 0
            # z统计量 (根据图片公式: z = (p̂ - p₀) / SE)
            z = (p_hat - p0) / SE if SE > 0 else 0
            # z的绝对值
            z_abs = abs(z)
            # 拒绝条件: |z| > z_{α/2}
            if z_abs > z_alpha_2:
                print(f"{p:8.4f} {n:8d} {k:8.0f} {p_hat:8.4f} {SE:10.6f} {z:8.4f} {z_abs:8.4f} {'是':>8}")
                found = True
                break
            n += 1
        if not found:
            print(f"{p:8.4f} {'未找到':>8}")
        delta += delta_step

if __name__ == "__main__":
    # 标称次品率p0=0.1，显著性水平alpha=0.05
    find_min_n_for_p(p0=0.1, alpha=0.95, delta_start=0.001, delta_end=0.1, delta_step=0.001, max_n=10000)